# -*- tcl -*-
# Engine to convert a doctoc document into HTML.
#
# Copyright (c) 2003-2019 Andreas Kupries <andreas_kupries@sourceforge.net>
# Freely redistributable.
#
######################################################################

dt_source _toc_common.tcl
dt_source _html.tcl

######################################################################
# Conversion specification.
#
# One-pass processing.

rename toc_postprocess {}
rename fmt_postprocess toc_postprocess

proc fmt_plain_text {text} {return {}}

################################################################
## Backend for HTML markup

proc fmt_toc_begin {label title} {
    set hdr ""
    if {![Get raw]} {
	append  hdr "[markup {<!DOCTYPE html>}]"
	append  hdr "[markup <html><head>]\n"
	append  hdr "[markup <title>] $label [markup </title>]\n"

	# Engine parameter - insert 'meta'
	if {[set meta [Get meta]] != {}} {append hdr [markup $meta]\n}

	append  hdr "[markup </head>]\n"
	append  hdr [ht_comment [c_provenance]]\n
	append  hdr [ht_comment "$label"]\n
	append  hdr \n
	append  hdr [markup <body>]\n
    }
    
    # Engine parameter - insert 'header'
    if {[set header [Get header]] != {}} {
	lappend map @TITLE@ $label
	set header [string map $map $header]
	append hdr [markup $header]\n
    }

    append hdr [markup <h3>]
    append hdr $label
    append hdr [markup </h3>] \n
    append hdr [markup <hr><dl><dt><h2>]
    append hdr $title
    append hdr [markup </h2></dt><dd>] \n
    LSetup
    IPush
    return $hdr
}

proc fmt_toc_end {} {
    set text "\n"
    # Close table of items since last division
    if {[Items]} { append text [tag/ table] \n }

    # Engine parameter - insert 'footer'
    set footer [Get footer]
    if {$footer != {}} {set footer \n[markup $footer]\n}

    append text [tag /dd] [tag /dl] [tag hr] $footer

    if {![Get raw]} {
	append text [tag/ body] [tag/ html] \n
    }

    IPop ; # Assert items == {}
    LOut ; # Assert level == 0
    return $text
}

proc fmt_division_start {title symfile} {
    # Close table of items before the division.  Reset counter for
    # items between end of this and following division.
    if {[Items]} { append r [tag/ table] \n ; IReset }
        
    if {$symfile ne ""} {
	append t [markup "<a href=\"[dt_fmap $symfile]\">"]
	append t $title
	append t [markup </a>]
	set title $t
    }

    append r \n [markup "<dl><dt><a name='[Anchor $title]'>"]
    append r $title
    append r [markup </dt><dd>]

    LIn
    IPush
    return $r
}

proc fmt_division_end {} {
    if {[Items]} { append t [tag/ table] }
    append t [tag /dl]
    Even!
    IPop
    LOut
    return $t
}

proc fmt_item {file label desc} {
    if {[IFirst]} { append text \n[markup "<table class=\"#doctools_toc\">"]\n }
    INext

    if {[Even]} {
	append text [markup "<tr class=\"#doctools_toceven\" >"]\n
    } else {
	append text [markup "<tr class=\"#doctools_tocodd\"  >"]\n
    }
    EFlip
    append text [markup "<td class=\"#doctools_tocleft\" >"]
    append text [markup "<a name='[Anchor $label]'><a href=\"[dt_fmap $file]\">"]
    append text $label
    append text [tag/ a][tag/ td]\n
    append text [markup "<td class=\"#doctools_tocright\">"]${desc}[tag /td]\n
    append text [tag/ tr]\n
    return $text
}

proc fmt_comment {text} {ht_comment $text}

################################################################

proc Term {text} { return [tag dt]${text}[tag /dt] }
proc Def  {text} { return [tag dd]${text}[tag /dd] }

proc Anchor {text} {
    set anchor [regsub -all {[^a-zA-Z0-9]} [string tolower $text] {_}]
    set anchor [regsub -all {__+} $anchor _]
    return $anchor
}

################################################################

global __level
global __items  ; set __items  {}
global __istack ; set __istack {}
global __even   ; set __even   1

proc Even! {} { global __even ; set __even 1 }
proc Even  {} { global __even ; set __even }
proc EFlip {} { global __even ; set __even [expr {1 - $__even}] }
    

proc LSetup {} { global __level ; set  __level  0 }
proc LIn    {} { global __level ; incr __level  1 }
proc LOut   {} { global __level ; incr __level -1 }
proc LTop   {} { global __level ; expr {!$__level } }

proc IReset {} { global __items ; set  __items 0 }
proc INext  {} { global __items ; incr __items }
proc IFirst {} { global __items ; expr {!$__items} }
proc Items  {} { global __items ; set __items }

proc IPush {} {
    global  __istack  __items
    lappend __istack $__items
    set __items 0
    return
}

proc IPop {} {
    global __items __istack
    set __items  [lindex   $__istack end]
    set __istack [lreplace $__istack end end]
    return
}

################################################################

global    __var
array set __var {
    meta   {}
    header {}
    footer {}
    raw    0
}
proc Get               {varname}      {global __var ; return $__var($varname)}
proc toc_listvariables {}             {global __var ; return [array names __var]}
proc toc_varset        {varname text} {
    global __var
    if {![info exists __var($varname)]} {return -code error "Unknown engine variable \"$varname\""}
    set __var($varname) $text
    return
}

################################################################
